package com.xinsoft.jobs;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xinsoft.constant.Const;
import com.xinsoft.entity.dto.SysNoticeDTO;
import com.xinsoft.entity.dto.SysNoticeSetDTO;
import com.xinsoft.entity.po.*;
import com.xinsoft.entity.vo.SysNoticeUserVo;
import com.xinsoft.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 物料长时间未使用通知
 */
@Slf4j
@EnableScheduling
@Component
public class MaterialTimeoutNoticeJob {

    @Autowired
    private ScmStockService stockService;
    @Autowired
    private SysNoticeSetService sysNoticeSetService;
    @Autowired
    private SysNoticeService sysNoticeService;
    @Autowired
    private SysMaterialService sysMaterialService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysActionService actionService;


    /**
     * 每天10点钟检查一次
     */
    @Scheduled(cron = "0 0 10 1/1 * ?")
    // @Scheduled(cron = "0 0/1 * * * ?")
    public void timeoutReminder() {
        log.info("=========================发送物料长时间未使用提醒开始=========================");
        List<ScmStock> stockList = stockService.list(Wrappers.lambdaQuery(ScmStock.class)
                .eq(ScmStock::getStockType, Const.DOCUMENT_ID.PRODUCE_INSTOCK_DOCUMENT)
                .gt(true, ScmStock::getBatchNumFree, 0));
        Date now = new Date();
        // 过滤出超过180天的物料
        List<ScmStock> list = stockList.stream().filter(stock -> DateUtil.between(now, stock.getCreateTime(), DateUnit.DAY) > 180).collect(Collectors.toList());
        List<Integer> materialIds = list.stream().map(ScmStock::getMaterialId).collect(Collectors.toList());
        List<SysMaterial> materialList = sysMaterialService.listByIds(materialIds);
        Map<Integer, SysMaterial> materialMap = materialList.stream().collect(Collectors.toMap(SysMaterial::getId, o -> o));
        // 发送消息提醒
        list.forEach(item -> {
            SysNoticeDTO notice = new SysNoticeDTO();
            notice.setFromUserId(1);   // 管理员发送
            notice.setContent(String.format("物料 %s 已经 %s 天未出库了，请及时使用", materialMap.get(item.getMaterialId()).getMaterialName(), DateUtil.between(now, item.getCreateTime(), DateUnit.DAY)));
            this.sendNoticeByActionId(Const.ACTION.MATERIAL_TIMEOUT_ALERT, notice);
        });
        log.info("=========================发送物料长时间未使用提醒结束=========================");
    }

    public void sendNoticeByActionId(Integer actionId, SysNoticeDTO notice) {
        List<SysNoticeSetDTO> sysNoticeSetDTOList = sysNoticeSetService.getSysNoticeSetByActionId(actionId);
        if (CollectionUtil.isNotEmpty(sysNoticeSetDTOList)) {
            for (SysNoticeSetDTO sysNoticeSetDTO : sysNoticeSetDTOList) {

                List<Integer> receiveIds = new ArrayList<>();
                List<Integer> deptIds = new ArrayList<>();
                List<SysNoticeUserVo> sysNoticeUserList = sysNoticeSetDTO.getSysNoticeUserList();
                if (CollectionUtil.isNotEmpty(sysNoticeUserList)) {
                    for (SysNoticeUser sysNoticeUser : sysNoticeUserList) {
                        if (Objects.equals(sysNoticeUser.getDepOrUser(), Const.NOTICE_DEPT)) {
                            deptIds.add(sysNoticeUser.getDepId());
                        }
                        if (Objects.equals(sysNoticeUser.getDepOrUser(), Const.NOTICE_USER)) {
                            receiveIds.add(sysNoticeUser.getUserId());
                        }
                    }
                }
                // 设置接收人
                if (CollectionUtil.isNotEmpty(deptIds)) {
                    List<SysUser> userList = sysUserService.list(Wrappers.lambdaQuery(SysUser.class)
                            .eq(SysUser::getStatus, Const.USER_STATUS_NORMAL)
                            .in(SysUser::getDeptId, deptIds));
                    if (CollectionUtil.isNotEmpty(userList)) {
                        for (SysUser sysUser : userList) {
                            receiveIds.add(sysUser.getId());
                        }
                    }
                }

                // 保存通知消息
                SysAction sysAction = actionService.getById(actionId);
                if (StrUtil.isNotBlank(sysAction.getActionName())) {
                    notice.setTitle(sysAction.getActionName());
                } else {
                    notice.setTitle("未配置消息标题");
                }
                notice.setReceiveIds(receiveIds);
                // 发送
                sysNoticeService.send(notice);
            }
        }
    }
}
